package com.chess.config;

import java.lang.reflect.Field;
import java.util.Set;

import com.chess.constant.AppConstant;
import com.jfinal.kit.PropKit;
import com.jfinal.log.Log;
import com.sojoys.artifact.core.IModule;
import com.sojoys.artifact.core.Modules;
import com.sojoys.artifact.manager.PropManager;
import com.xiaoleilu.hutool.lang.Filter;
import com.xiaoleilu.hutool.util.ClassUtil;

/**
 * 扫描Controller上的注解，绑定Controller和controllerKey
 * 
 * @author 董华健 dongcb678@163.com
 */
public class ModuleScan extends Modules{

	private static final Log log = Log.getLog(ModuleScan.class);

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Modules config() {
//		Set<Class<?>> scanClasses = ClassUtil.scanPackage(PropKit.get(AppConstant.HANDLER_SCAN_PACKAGE), new Filter<Class<?>>() {
//			@Override
//			public boolean accept(Class<?> clazz) {
//				return true;
//			}
//		});
		Set<Class<?>> scanClasses = ClassUtil.scanPackageBySuper(PropManager.get(AppConstant.MODULE_SCAN_PACKAGE),IModule.class);
		for (Class scanClass : scanClasses) {
			if (scanClass.isInterface()) {
				continue;
			}
			Object impl = ClassUtil.newInstance(scanClass);
			Object classCode = getFieldValue(impl, "classCode");
			if (classCode!=null) {
				// 注册映射
				add((byte) classCode,(IModule) impl);
				if (log.isDebugEnabled())
					log.debug("Module注册： Module = " + impl + ", " + classCode);
			}
		}
		return this;
	}

	public static Object getFieldValue(Object object, String fieldName) {

		// 根据 对象和属性名通过反射 调用上面的方法获取 Field对象
		Field field = getDeclaredField(object, fieldName);
		// 抑制Java对其的检查
		field.setAccessible(true);
		try {
			// 获取 object 中 field 所代表的属性值
			return field.get(object);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static Field getDeclaredField(Object object, String fieldName) {
		Field field = null;
		Class<?> interfaces[] = object.getClass().getInterfaces();// 获得Dog所实现的所有接口
		for (Class<?> clazz : interfaces) {
			try {
				field = clazz.getDeclaredField(fieldName);
			} catch (NoSuchFieldException | SecurityException e) {
				e.printStackTrace();
			}
			return field;
		}
		return null;
	}
}
